// Import necessary modules
import fileObject from '@/common/upload/fileObject.js';
import StorageCache from '@/common/mediacache/index.js';

//初始化队列和活动上传计数
const uploadQueue = [];
let activeUploads = 0;
const MAX_CONCURRENT_UPLOADS = 2;
const MAX_CONCURRENT_SLICE_UPLOADS = 5;

//处理队列中下一个上传的函数
const processNextUpload = () => {
	if (uploadQueue.length > 0 && activeUploads < MAX_CONCURRENT_UPLOADS) {
		const { filepath,uptype,filetype,resolve,reject } = uploadQueue.shift();
		uploadFile(filepath, uptype, filetype).then(resolve).catch(reject).finally(() => {
			activeUploads--;
			processNextUpload();
		});
		activeUploads++;
	}
};

//处理文件上传的函数
function uploadFile(filepath, uptype, filetype) {
	return new Promise(async (resolve, reject) => {
		let fileTypeObject = await fileObject.from_file(filepath, uptype, filetype);
		let yudata = fileTypeObject.toRequest();
		try {
			let yures = await uni.$api.unload.fileUpload(yudata);
			if (yures) {
				if (yures.code == 2003) {
					// Cache the local image
					StorageCache.setCachedUrl(`${filetype}_${uptype}_cache_list`, yures.data.url, filepath);
					resolve(yures.data);
					return;
				}
				if (yudata.file_total) {
					let signedUrlArr = yures.data.file_url;
					let sliceList = await fileTypeObject.toSliceBuffer();
					try {
						const resall = await uploadSlices(signedUrlArr, sliceList);
						let Etags = resall.sort((a, b) => a.index - b.index).map((res) => ({ PartNumber: res.index + 1, ETag: JSON.parse(res.header.ETag) }));
						let completejson = {
							upload_name: yures.data.upload_name,
							resource_type: yudata.resource_type,
							file_hash: yudata.file_hash,
							upload_type: yudata.upload_type,
							file_total: yudata.file_total,
							upload_id: yures.data.upload_id,
							parts: Etags
						};
						let completeData = await uni.$api.unload.uploadComplete(completejson);
						if (completeData) {
							StorageCache.setCachedUrl(`${filetype}_${uptype}_cache_list`, completeData.data
								.url, filepath);
							resolve(completeData.data);
						} else {
							reject('Upload completion failed');
						}
					} catch (e) {
						reject('Some slices failed');
					}
				} else {
					let arrayBuffer = await fileTypeObject.toBuffer();
					await upload(yures.data.url, arrayBuffer);
					let completejson = {
						upload_name: yures.data.upload_name,
						resource_type: yudata.resource_type,
						file_hash: yudata.file_hash,
						upload_type: yudata.upload_type,
						file_total: yudata.file_total,
						upload_id: 0
					};
					let completeData = await uni.$api.unload.uploadComplete(completejson);
					if (completeData) {
						//缓存本地镜像
						StorageCache.setCachedUrl(`${filetype}_${uptype}_cache_list`, completeData.data.url,
							filepath);
						resolve(completeData.data);
					} else {
						reject('Upload completion failed');
					}
				}
			} else {
				reject('Upload error');
			}
		} catch (e) {
			reject(e);
		}
	});
}
// 带有并发控制的分片上传函数
const uploadSlices = (signedUrlArr, sliceList) => {
	return new Promise((resolve, reject) => {
		let activeSliceUploads = 0;
		let completedSlices = 0;
		const totalSlices = signedUrlArr.length;
		const sliceUploadQueue = signedUrlArr.map((url, index) => ({ url, slice: sliceList[index], index }));
		const resall = [];

		const processNextSliceUpload = () => {
			if (sliceUploadQueue.length > 0 && activeSliceUploads < MAX_CONCURRENT_SLICE_UPLOADS) {
				const { url, slice, index } = sliceUploadQueue.shift();
				console.log(slice.byteLength,'---',index);
				upload(url, slice).then(res => {
					console.log(slice.byteLength,'---',index);
					resall.push({ ...res, index });
					completedSlices++;
					if (completedSlices === totalSlices) {
						resolve(resall);
					} else {
						processNextSliceUpload();
					}
				}).catch(reject).finally(() => {
					activeSliceUploads--;
					processNextSliceUpload();
				});
				activeSliceUploads++;
			}
		};

		for (let i = 0; i < MAX_CONCURRENT_SLICE_UPLOADS; i++) {
			processNextSliceUpload();
		}
	});
};

//简单的上传函数
function upload(url, arrayBuffer) {
	return new Promise((resolve, reject) => {
		uni.uploadFile({
			url,
			filePath:arrayBuffer,
			success:(res)=>{
				console.log(res);
			},
			fail: (e) => {
				console.log(e);
			}
		})
		return
		console.log(url);
		uni.$u.http.put(url, arrayBuffer, {
			timeout: 5000,
			custom: {
				native: true
			}
		}).then(res => {
			console.log('1233333');
			if (res !== false) {
				resolve(res);
			} else {
				reject('Upload failed');
			}
		}).catch(err => {
			console.log('1233333',err);
			reject(err);
		});
	});
}

//带有队列的公共请求函数
function request(filepath, uptype, filetype) {
	return new Promise((resolve, reject) => {
		uploadQueue.push({
			filepath,
			uptype,
			filetype,
			resolve,
			reject
		});
		console.log(uploadQueue);
		processNextUpload();
	});
}

export default {
	request
};